﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;
using System.Net;
using System.IO;
using System.Net.Mime;
using System.ComponentModel;

namespace JWFW.SFL
{
    /// <summary>
    /// 邮件发送程序
    /// </summary>
    public class MailOP
    {

        /// <summary>
        /// 异步发送邮件时启用的邮件发送完成通知
        /// </summary>
        public static event SendCompletedEventHandler OnSendCompleted;

        private string m_server = "";
        private string m_userName = "";
        private string m_pwd = "";
        private string m_fromMail = "";
        private string m_toMail = "";
        private string m_ccMail = "";
        private string m_bccMail = "";
        private string m_subject = "";
        private string m_body = "";
        private bool m_htmlBody = false;
        private string m_attachFileName = "";
        private int? m_port = null;
        private bool? m_ssl = null;
        private bool? m_needBack = null;
        private bool? m_noticeFail = null;
        private bool? m_async = null;
        private object m_asyncID = null;
        private List<Attachment> m_attachmentList = new List<Attachment>();
        private object m_tag = null;



        /// <summary>
        /// 邮件服务器
        /// </summary>
        public string Server
        {
            get { return m_server; }
            set { m_server = value; }
        }
        /// <summary>
        /// 登录到邮件服务器的用户名
        /// </summary>
        public string UserName
        {
            get { return m_userName; }
            set { m_userName = value; }
        }
        /// <summary>
        /// 登录到邮件服务器的密码
        /// </summary>
        public string Pwd
        {
            get { return m_pwd; }
            set { m_pwd = value; }
        }
        /// <summary>
        /// 显示发送人的邮件地址
        /// </summary>
        public string FromMail
        {
            get { return m_fromMail; }
            set { m_fromMail = value; }
        }
        /// <summary>
        /// 目标地址
        /// </summary>
        public string ToMail
        {
            get { return m_toMail; }
            set { m_toMail = value; }
        }
        /// <summary>
        /// 抄送地址
        /// </summary>
        public string CcMail
        {
            get { return m_ccMail; }
            set { m_ccMail = value; }
        }
        /// <summary>
        /// 密件抄送地址：不显示给其他收件人的抄送列表里
        /// </summary>
        public string BccMail
        {
            get { return m_bccMail; }
            set { m_bccMail = value; }
        }
        /// <summary>
        /// 邮件主题
        /// </summary>
        public string Subject
        {
            get { return m_subject; }
            set { m_subject = value; }
        }
        /// <summary>
        /// 邮件内容
        /// </summary>
        public string Body
        {
            get { return m_body; }
            set { m_body = value; }
        }
        /// <summary>
        /// 是否按照html格式显示
        /// </summary>
        public bool HtmlBody
        {
            get { return m_htmlBody; }
            set { m_htmlBody = value; }
        }
        /// <summary>
        /// 邮件附件的文件名：本地的全名
        /// </summary>
        public string AttachFileName
        {
            get { return m_attachFileName; }
            set { m_attachFileName = value; }
        }
        /// <summary>
        /// 邮件服务器使用的端口
        /// </summary>
        public int? Port
        {
            get { return m_port; }
            set { m_port = value; }
        }
        /// <summary>
        /// 邮件服务器是否需要ssl加密
        /// </summary>
        public bool? Ssl
        {
            get { return m_ssl; }
            set { m_ssl = value; }
        }
        /// <summary>
        /// 需要回条
        /// </summary>
        public bool? NeedBack
        {
            get { return m_needBack; }
            set { m_needBack = value; }
        }
        /// <summary>
        /// 发送失败提醒
        /// </summary>
        public bool? NoticeFail
        {
            get { return m_noticeFail; }
            set { m_noticeFail = value; }
        }
        /// <summary>
        /// 是否异步发送
        /// </summary>
        public bool? Async
        {
            get { return m_async; }
            set { m_async = value; }
        }
        /// <summary>
        /// 异步发送时使用的标识
        /// </summary>
        public object AsyncID
        {
            get { return m_asyncID; }
            set { m_asyncID = value; }
        }
        /// <summary>
        /// 指定特征的附件
        /// </summary>
        public List<Attachment> AttachmentList
        {
            get { return m_attachmentList; }
        }

        /// <summary>
        /// 本类相关的信息
        /// </summary>
        public object Tag
        {
            get { return m_tag; }
            set { m_tag = value; }
        }

        /// <summary>
        /// 添加嵌入的图片资源
        /// </summary>
        /// <param name="fileName">资源的文件全名</param>
        /// <returns>该资源的标识</returns>
        public string AddNewImage(string fileName)
        {
            string res = Guid.NewGuid().ToString().Substring(0, 8);
            Attachment att = new Attachment(fileName);
            att.ContentId = res;
            m_attachmentList.Add(att);
            return "cid:" + res;
        }

        /// <summary>
        /// 添加收件人
        /// </summary>
        /// <param name="msg">邮件消息对象</param>
        /// <param name="to">收件人地址，多个收件人使用";"分割</param>
        protected static void AddTO(MailMessage msg, string to)
        {
            string[] tos = CommonOP.SplitString(to, ";");
            for (int i = 0; i < tos.Length; i++)
            {
                MailAddress tmp = new MailAddress(tos[i]);
                msg.To.Add(tmp);
            }
        }
        /// <summary>
        /// 添加附件
        /// </summary>
        /// <param name="msg">邮件消息对象</param>
        /// <param name="attFile">附件的文件名，多个附件使用";"分割</param>
        /// <param name="attachList">已附件对象形式存在的附件列表</param>
        protected static void AddAttach(MailMessage msg, string attFile, List<Attachment> attachList)
        {
            if (!string.IsNullOrEmpty(attFile))
            {
                string[] atts = CommonOP.SplitString(attFile, ";");
                for (int i = 0; i < atts.Length; i++)
                {
                    Attachment tmp = new Attachment(atts[i], MediaTypeNames.Application.Octet);
                    //附件信息
                    ContentDisposition disposition = tmp.ContentDisposition;
                    disposition.CreationDate = File.GetCreationTime(atts[i]);
                    disposition.ModificationDate = File.GetLastWriteTime(atts[i]);
                    disposition.ReadDate = File.GetLastAccessTime(atts[i]);
                    msg.Attachments.Add(tmp);
                }
            }
            if (attachList != null)
            {
                for (int i = 0; i < attachList.Count; i++)
                {
                    msg.Attachments.Add(attachList[i]);
                }
            }
        }
        /// <summary>
        /// 添加抄送
        /// </summary>
        /// <param name="msg">邮件消息对象</param>
        /// <param name="cc">抄送人，多个抄送人使用";"分割</param>
        protected static void AddCC(MailMessage msg, string cc)
        {
            if (string.IsNullOrEmpty(cc))
            {
                return;
            }
            string[] ccs = CommonOP.SplitString(cc, ";");
            for (int i = 0; i < ccs.Length; i++)
            {
                MailAddress tmp = new MailAddress(ccs[i]);
                msg.CC.Add(tmp);
            }
        }
        /// <summary>
        /// 添加匿名抄送
        /// </summary>
        /// <param name="msg">邮件消息对象</param>
        /// <param name="bcc">匿名抄送人，多个匿名抄送人使用";"分割</param>
        protected static void AddBCC(MailMessage msg, string bcc)
        {
            if (string.IsNullOrEmpty(bcc))
            {
                return;
            }
            string[] ccs = CommonOP.SplitString(bcc, ";");
            for (int i = 0; i < ccs.Length; i++)
            {
                MailAddress tmp = new MailAddress(ccs[i]);
                msg.Bcc.Add(tmp);
            }
        }
        /// <summary>
        /// 登录SMTP服务器并发送邮件
        /// </summary>
        /// <param name="msg">邮件消息对象</param>
        /// <param name="server">SMTP服务器地址</param>
        /// <param name="userName">登录SMTP服务器的用户名</param>
        /// <param name="pwd">登录SMTP服务器的密码</param>
        /// <param name="port">SMTP服务器的端口号，可为null</param>
        /// <param name="ssl">SMTP服务器是否使用SSL安全传输，可为null</param>
        /// <param name="async">是否异步发送，可为null</param>
        /// <param name="asyncID">异步发送时的标识</param>
        protected static void Send(MailMessage msg, string server, string userName, string pwd, int? port, bool? ssl, bool? async, object asyncID)
        {
            SmtpClient client = new SmtpClient(server);
            if (!(userName == null || pwd == null || userName == ""))
            {
                client.Credentials = new NetworkCredential(userName, pwd);
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                if (port != null)
                {
                    client.Port = (int)port;
                }
                if (ssl != null)
                {
                    client.EnableSsl = (bool)ssl;
                }
            }
            if (async != null && (bool)async)
            {
                client.SendCompleted += new SendCompletedEventHandler(client_SendCompleted);
                client.SendAsync(msg, asyncID);
            }
            else
            {
                client.Send(msg);
            }
        }

        private static void client_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (OnSendCompleted != null)
            {
                OnSendCompleted(sender, e);
            }
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="server">SMTP服务器地址</param>
        /// <param name="userName">登录SMTP服务器的用户名</param>
        /// <param name="pwd">登录SMTP服务器的密码</param>
        /// <param name="fromMail">显示发件的Email</param>
        /// <param name="toMail">收件人地址，多个收件人使用";"分割</param>
        /// <param name="ccMail">抄送人，多个抄送人使用";"分割</param>
        /// <param name="bccMail">匿名抄送人，多个匿名抄送人使用";"分割</param>
        /// <param name="subject">邮件主题</param>
        /// <param name="body">邮件正文</param>
        /// <param name="htmlBody">是否显示HTML格式</param>
        /// <param name="attachFileName">附件的文件名，多个附件使用";"分割</param>
        /// <param name="attachList">已附件对象形式存在的附件列表</param>
        /// <param name="port">SMTP服务器的端口号，可为null</param>
        /// <param name="ssl">SMTP服务器是否使用SSL安全传输，可为null</param>
        /// <param name="async">是否异步发送，可为null</param>
        /// <param name="asyncID">异步发送时的标识</param>
        /// <param name="needBack">是否需要回执功能，可为null</param>
        /// <param name="noticeFail">是否接受发送失败通知，可为null</param>
        public static void SendMail(string server, string userName, string pwd, string fromMail, string toMail,
            string ccMail, string bccMail, string subject, string body, bool htmlBody, string attachFileName, List<Attachment> attachList,
            int? port, bool? ssl, bool? async, object asyncID, bool? needBack, bool? noticeFail)
        {
            MailMessage msg = new MailMessage();
            if (!string.IsNullOrEmpty(fromMail))
            {
                msg.From = new MailAddress(fromMail);
            }
            msg.Subject = subject;
            msg.Body = body;
            msg.IsBodyHtml = htmlBody;
            if (needBack != null && (bool)needBack)
            {
                msg.Headers.Add("Disposition-Notification-To", fromMail);
                msg.Headers.Add("ReturnReceipt", "1");
            }
            if (noticeFail != null && (bool)noticeFail)
            {
                msg.DeliveryNotificationOptions = msg.DeliveryNotificationOptions | DeliveryNotificationOptions.OnFailure;
            }
            AddTO(msg, toMail);
            AddCC(msg, ccMail);
            AddBCC(msg, bccMail);
            AddAttach(msg, attachFileName, attachList);
            Send(msg, server, userName, pwd, port, ssl, async, asyncID);
        }
        /// <summary>
        /// 发送邮件
        /// </summary>
        public void SendMail()
        {
            SendMail(m_server, m_userName, m_pwd, m_fromMail, m_toMail,
                m_ccMail, m_bccMail, m_subject, m_body, m_htmlBody, m_attachFileName, m_attachmentList,
                m_port, m_ssl, m_async, m_asyncID, m_needBack, m_noticeFail);
        }

        protected void Test()
        {
            MailOP mop = new MailOP();
            string id = mop.AddNewImage(@"e:\clr.jpg");
            mop.m_userName = "baoyang@seiosoft.com";
            mop.m_pwd = "baoyang";
            mop.m_toMail = "testbao@gmail.com";
            mop.m_server = "smtp.seiosoft.com";
            mop.m_port = 25;
            mop.m_ssl = false;
            //mop.Async = true;
            mop.m_htmlBody = true;
            mop.m_subject = "Test Email image";
            mop.m_fromMail = "baoyang@seiosoft.com";
            mop.m_body = string.Format("<span style='color:blue'>TEST Embed IMAGE</span><IMG src='{0}'/>", id);
            mop.SendMail();
            return;
            //SendMail("smtp.gmail.com", "testbao@gmail.com", "anhuichaohu", "hubo1516@gmail.com ",
                //"aaron.bao@seioglobal123.com", null, null, "test12345", "just a test", true, "", null, 587, true, true, null, true, true);
        }

}
